"""
事件总线管理器 - 替代全局单例模式，提供依赖注入支持
"""

import threading
from typing import Dict, Optional, Set
from .bus import EventBus

class EventBusManager:
    """
    事件总线管理器
    
    负责创建和管理事件总线实例，替代全局单例模式。
    提供线程安全的实例管理和生命周期控制。
    """
    
    def __init__(self):
        self._buses: Dict[str, EventBus] = {}
        self._lock = threading.RLock()
        self._created_buses: Set[str] = set()
    
    def create_bus(self, name: str) -> EventBus:
        """
        创建新的事件总线实例
        
        Args:
            name: 事件总线名称
            
        Returns:
            EventBus: 新创建的事件总线实例
            
        Raises:
            ValueError: 如果同名事件总线已存在
        """
        with self._lock:
            if name in self._buses:
                raise ValueError(f"Event bus '{name}' already exists")
            
            bus = EventBus(name)
            self._buses[name] = bus
            self._created_buses.add(name)
            return bus
    
    def get_bus(self, name: str) -> Optional[EventBus]:
        """
        获取现有的事件总线实例
        
        Args:
            name: 事件总线名称
            
        Returns:
            Optional[EventBus]: 事件总线实例，如果不存在则返回None
        """
        with self._lock:
            return self._buses.get(name)
    
    def get_or_create_bus(self, name: str) -> EventBus:
        """
        获取或创建事件总线实例
        
        Args:
            name: 事件总线名称
            
        Returns:
            EventBus: 事件总线实例
        """
        with self._lock:
            bus = self._buses.get(name)
            if bus is None:
                bus = self.create_bus(name)
            return bus
    
    def remove_bus(self, name: str) -> bool:
        """
        移除事件总线实例
        
        Args:
            name: 事件总线名称
            
        Returns:
            bool: 是否成功移除
        """
        with self._lock:
            bus = self._buses.pop(name, None)
            if bus is not None:
                # 清理事件总线资源
                bus.clear_handlers()
                self._created_buses.discard(name)
                return True
            return False
    
    def list_buses(self) -> Dict[str, Dict]:
        """
        列出所有事件总线及其统计信息
        
        Returns:
            Dict[str, Dict]: 事件总线名称到统计信息的映射
        """
        with self._lock:
            return {
                name: bus.get_stats() 
                for name, bus in self._buses.items()
            }
    
    def clear_all(self):
        """清理所有事件总线"""
        with self._lock:
            for bus in self._buses.values():
                bus.clear_handlers()
            self._buses.clear()
            self._created_buses.clear()
    
    def get_stats(self) -> Dict:
        """
        获取管理器统计信息
        
        Returns:
            Dict: 统计信息
        """
        with self._lock:
            total_handlers = sum(
                bus.get_stats().get('active_handlers', 0) 
                for bus in self._buses.values()
            )
            total_events = sum(
                bus.get_stats().get('events_published', 0) 
                for bus in self._buses.values()
            )
            
            return {
                'total_buses': len(self._buses),
                'bus_names': list(self._buses.keys()),
                'total_handlers': total_handlers,
                'total_events_published': total_events,
                'created_buses': list(self._created_buses)
            }

class TestEventBusManager:
    """
    测试专用事件总线管理器
    
    为测试提供隔离的事件总线实例，确保测试之间不会相互影响。
    """
    
    def __init__(self):
        self._test_buses: Dict[str, EventBus] = {}
        self._lock = threading.RLock()
    
    def create_test_bus(self, test_name: str) -> EventBus:
        """
        为测试创建隔离的事件总线
        
        Args:
            test_name: 测试名称
            
        Returns:
            EventBus: 测试专用的事件总线实例
        """
        with self._lock:
            bus_name = f"test_{test_name}_{id(self)}"
            bus = EventBus(bus_name)
            self._test_buses[test_name] = bus
            return bus
    
    def get_test_bus(self, test_name: str) -> Optional[EventBus]:
        """
        获取测试事件总线
        
        Args:
            test_name: 测试名称
            
        Returns:
            Optional[EventBus]: 测试事件总线实例
        """
        with self._lock:
            return self._test_buses.get(test_name)
    
    def cleanup_test_bus(self, test_name: str):
        """
        清理测试事件总线
        
        Args:
            test_name: 测试名称
        """
        with self._lock:
            if test_name in self._test_buses:
                bus = self._test_buses[test_name]
                bus.clear_handlers()
                del self._test_buses[test_name]
    
    def cleanup_all(self):
        """清理所有测试事件总线"""
        with self._lock:
            for bus in self._test_buses.values():
                bus.clear_handlers()
            self._test_buses.clear()
    
    def get_stats(self) -> Dict:
        """
        获取测试管理器统计信息
        
        Returns:
            Dict: 统计信息
        """
        with self._lock:
            return {
                'active_test_buses': len(self._test_buses),
                'test_names': list(self._test_buses.keys()),
                'total_test_handlers': sum(
                    bus.get_stats().get('active_handlers', 0) 
                    for bus in self._test_buses.values()
                )
            }

# 测试装饰器
import functools
from typing import Callable, TypeVar

F = TypeVar('F', bound=Callable)

def with_test_event_bus(func: F) -> F:
    """
    为测试函数提供隔离的事件总线
    
    这个装饰器会为每个测试函数创建一个独立的事件总线实例，
    确保测试之间完全隔离，不会相互影响。
    
    Usage:
        @with_test_event_bus
        def test_something(event_bus):
            # 使用隔离的事件总线
            event_bus.subscribe("test_event", handler)
            event_bus.publish("test_event", "data")
    """
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        test_name = func.__name__
        manager = TestEventBusManager()
        test_bus = manager.create_test_bus(test_name)
        
        try:
            # 将测试事件总线注入到测试函数中
            return func(*args, event_bus=test_bus, **kwargs)
        finally:
            manager.cleanup_test_bus(test_name)
    
    return wrapper

def with_isolated_event_bus(bus_name: str = None):
    """
    为函数提供隔离的事件总线实例
    
    Args:
        bus_name: 可选的总线名称，如果不提供则使用函数名
    
    Usage:
        @with_isolated_event_bus("my_test")
        def test_function(event_bus):
            # 使用隔离的事件总线
            pass
    """
    def decorator(func: F) -> F:
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            name = bus_name or func.__name__
            manager = EventBusManager()
            isolated_bus = manager.create_bus(f"isolated_{name}_{id(wrapper)}")
            
            try:
                return func(*args, event_bus=isolated_bus, **kwargs)
            finally:
                manager.remove_bus(isolated_bus.name)
        
        return wrapper
    return decorator
